package fr.asip.cps3.exemple.modele.objets;


import iaik.pkcs.pkcs11.wrapper.CK_ATTRIBUTE;
import iaik.pkcs.pkcs11.wrapper.PKCS11;
import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
import iaik.pkcs.pkcs11.wrapper.PKCS11Exception;

import org.apache.log4j.Logger;

import fr.asip.cps3.exemple.modele.exceptions.ExceptionObjet;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionProgrammeExemple;
import fr.asip.cps3.exemple.modele.traitements.util.TraitementsUtil;

/**
 * Classe modélisant un objet de données applicatives
 */
public class Objet {

	/**
	 * Le loggeur
	 */
	 private static Logger log = Logger.getLogger(Objet.class);
	
	/**
	 * Identifiant de l'objet
	 */
	private long idObjet;

	/**
	 * Libellé (CKA_LABEL) de l'objet
	 */
	private String libelle;

	/**
	 * Valeur (CKA_VALUE) de l'objet
	 */
	private String valeur;	
	
	/**
	 * Constructeur
	 * @param librairie Librairie PKCS#11 à utiliser
	 * @param idSession Identifiant de la session
	 * @param idObjet Identifiant de l'objet
	 * @throws ExceptionObjet 
	 */
	public Objet(PKCS11 librairie, long idSession, long idObjet) throws ExceptionObjet {
		
		this.idObjet = idObjet;
		
		chargeInfo(librairie, idSession);
		
	}

	/**
	 * (Re)chargement explicite des informations de l'objet
	 * @param librairie Librairie PKCS#11 à utiliser
	 * @param idSession Identifiant de la session
	 * @throws ExceptionObjet
	 */
	public void chargeInfo(PKCS11 librairie, long idSession) throws ExceptionObjet {

		if(librairie != null) {
			

			try{
				// Collecte de quelques informations concernant l'objet
		
				CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[2];
				attributes[0] = new CK_ATTRIBUTE();
				attributes[0].type = PKCS11Constants.CKA_LABEL;
				attributes[1] = new CK_ATTRIBUTE();
				attributes[1].type = PKCS11Constants.CKA_VALUE;
				librairie.C_GetAttributeValue(idSession, idObjet, attributes);
				if(attributes != null && attributes.length != 0) {
					try {
						libelle = new String((char[])attributes[0].pValue);
						valeur = TraitementsUtil.getHexadecimal((byte[])attributes[1].pValue,16);
					} catch(ClassCastException e) {
						log.error("Une erreur est survenue lors de la recuperation des informations de l'objet : "+ExceptionProgrammeExemple.getStacktrace(e));
						throw new ExceptionObjet(ExceptionProgrammeExemple.TYPE_OBJET_OBJET, "Une erreur est survenue lors de la récuperation des informations de l'objet");
					}	
				}

			} catch (PKCS11Exception e) {
				
				// Si une erreur PKCS#11 est rencontrée on log et on lève l'exception
				log.error("Une erreur est survenue lors de la recuperation des informations de l'objet : "+TraitementsUtil.retranscritCodeRetour(e.getErrorCode()));
				throw new ExceptionObjet(ExceptionProgrammeExemple.TYPE_OBJET_OBJET, "Une erreur est survenue lors de la récuperation des informations de l'objet");
				
				
			}
			
		} else {
			
			// Si la librairie est nulle il est impossible de récupérer les informations de l'objet
			log.error("La librairie est nulle");
			throw new ExceptionObjet(ExceptionProgrammeExemple.TYPE_OBJET_OBJET, "La librairie est nulle");
			
		}
	}


	/**
	 * Accesseur
	 * @return L'identifiant de l'objet
	 */
	public long getIdObjet() {
		return idObjet;
	}


	/**
	 * Accesseur
	 * @return Le libellé (CKA_LABEL) de l'objet  
	 */
	public String getLibelle() {
		return libelle;
	}

	/**
	 * Accesseur
	 * @return La valeur (CKA_VALUE) de l'objet
	 */
	public String getValeur() {
		return valeur;
	}
	

}
